home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.5)
-
- from eventloop import asIdle
- from platformutils import FilenameType
- import os.path as os
- import re
- import subprocess
- import time
- import traceback
- import threading
- import Queue
- import app
- import eventloop
- import logging
- import config
- import prefs
- import util
- MOVIE_DATA_UTIL_TIMEOUT = 60
- SLEEP_DELAY = 0.1
- durationRE = re.compile('Miro-Movie-Data-Length: (\\d+)')
- thumbnailSuccessRE = re.compile('Miro-Movie-Data-Thumbnail: Success')
- thumbnailRE = re.compile('Miro-Movie-Data-Thumbnail: (Success|Failure)')
-
- def thumbnailDirectory():
- dir = os.path.join(config.get(prefs.ICON_CACHE_DIRECTORY), 'extracted')
-
- try:
- os.makedirs(dir)
- except:
- pass
-
- return dir
-
-
- class MovieDataInfo:
- """Little utility class to keep track of data associated with each movie.
- This is:
-
- * The item.
- * The path to the video.
- * Path to the thumbnail we're trying to make.
- * List of commands that we're trying to run, and their environments.
- """
-
- def __init__(self, item):
- self.item = item
- self.videoPath = item.getVideoFilename()
- thumbnailFilename = '%s.%s.png' % (os.path.basename(self.videoPath), util.random_string(5))
- self.thumbnailPath = os.path.join(thumbnailDirectory(), thumbnailFilename)
- self.programInfo = []
- if hasattr(app, 'controller') and hasattr(app.controller, 'videoDisplay'):
- for renderer in app.controller.videoDisplay.renderers:
-
- try:
- (commandLine, env) = renderer.movieDataProgramInfo(self.videoPath, self.thumbnailPath)
- except NotImplementedError:
- continue
-
- self.programInfo.append((commandLine, env))
-
-
-
-
-
- class MovieDataUpdater:
-
- def __init__(self):
- self.inShutdown = False
- self.queue = Queue.Queue()
- self.thread = None
-
-
- def startThread(self):
- self.thread = threading.Thread(name = 'Movie Data Thread', target = self.threadLoop)
- self.thread.setDaemon(True)
- self.thread.start()
-
-
- def threadLoop(self):
- while not self.inShutdown:
- movieDataInfo = self.queue.get(block = True)
- if movieDataInfo is None:
- break
-
-
- try:
- duration = -1
- screenshotWorked = False
- screenshot = None
- for commandLine, env in movieDataInfo.programInfo:
- stdout = self.runMovieDataProgram(commandLine, env)
- if duration == -1:
- duration = self.parseDuration(stdout)
-
- if thumbnailSuccessRE.search(stdout):
- screenshotWorked = True
-
- if duration != -1 and screenshotWorked:
- break
- continue
-
- if screenshotWorked and os.path.exists(movieDataInfo.thumbnailPath):
- screenshot = movieDataInfo.thumbnailPath
- else:
- screenshot = FilenameType('')
- self.updateFinished(movieDataInfo.item, duration, screenshot)
- continue
- if self.inShutdown:
- break
-
-
- util.failedExn('When running external movie data program')
- self.updateFinished(movieDataInfo.item, -1, None)
- continue
-
-
- def runMovieDataProgram(self, commandLine, env):
- start_time = time.time()
- pipe = subprocess.Popen(commandLine, stdout = subprocess.PIPE, stdin = subprocess.PIPE, stderr = subprocess.PIPE, env = env, startupinfo = util.no_console_startupinfo())
- while pipe.poll() is None and not (self.inShutdown):
- time.sleep(SLEEP_DELAY)
- if time.time() - start_time > MOVIE_DATA_UTIL_TIMEOUT:
- logging.info('Movie data process hung, killing it')
- self.killProcess(pipe.pid)
- return ''
- continue
- if self.inShutdown:
- if pipe.poll() is None:
- logging.info('Movie data process running after shutdown, killing it')
- self.killProcess(pipe.pid)
-
- return ''
-
- return pipe.stdout.read()
-
-
- def killProcess(self, pid):
-
- try:
- app.delegate.killProcess(pid)
- except:
- logging.warn('Error trying to kill the movie data process:\n%s', traceback.format_exc())
-
- logging.info('Movie data process killed')
-
-
- def outputValid(self, stdout):
- if thumbnailRE.search(stdout) is not None:
- pass
- return durationRE.search(stdout) is not None
-
-
- def parseDuration(self, stdout):
- durationMatch = durationRE.search(stdout)
- if durationMatch:
- return int(durationMatch.group(1))
- else:
- return -1
-
-
- def updateFinished(self, item, duration, screenshot):
- if item.idExists():
- item.duration = duration
- item.screenshot = screenshot
- item.updating_movie_info = False
- item.resizeScreenshot()
- item.signalChange()
-
-
- updateFinished = asIdle(updateFinished)
-
- def requestUpdate(self, item):
- if self.inShutdown:
- return None
-
- filename = item.getVideoFilename()
- if not filename or not os.path.isfile(filename):
- return None
-
- if item.downloader and not item.downloader.isFinished():
- return None
-
- if item.updating_movie_info:
- return None
-
- item.updating_movie_info = True
- self.queue.put(MovieDataInfo(item))
-
-
- def shutdown(self):
- self.inShutdown = True
- self.queue.put(None)
- if self.thread is not None:
- self.thread.join()
-
-
-
- movieDataUpdater = MovieDataUpdater()
-